package com.server.common.code.utils;

import cn.hutool.core.img.GraphicsUtil;
import cn.hutool.core.img.Img;
import cn.hutool.core.img.ImgUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.io.resource.ResourceUtil;
import com.server.common.code.error.BusinessException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.ObjectUtils;

import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

@Slf4j
public class ImageUtils extends ImgUtil {
    /**
     * 水印图片
     */
    private static BufferedImage markIco = null;

    static {
        try {
            markIco = read(FileUtil.file(ResourceUtil.getResource("logo2.png")));
        } catch (Exception e) {
            log.error("加载水印失败!",e);
        }
    }

    /**
     * 按比例缩放
     */
    public static Image scale(Image srcImg, int width) {
        return Img.from(srcImg).scale(width, width * srcImg.getHeight(null) / srcImg.getWidth(null)).getImg();
    }

    /**
     * 创建缩略图
     * @author LXC
     * @date 2023/2/5 17:59
     */
    public static Image createThumbnail(Image bufferedImage, Integer scaleSize){
        if(ObjectUtils.isEmpty(scaleSize)){
            return addMark(bufferedImage, markIco,  1F);
        }
        int height = bufferedImage.getHeight(null);
        int width = bufferedImage.getWidth(null);

        //w/h=w1/h1
        int widthNew = width > height?scaleSize:scaleSize*width/height;
        int heightNew = width < height?scaleSize:scaleSize*height/width;

        Image bufferedImageNew = scale(bufferedImage, widthNew,heightNew);
        return addMark(bufferedImageNew, markIco,  1F);
    }

    /**
     * 创建缩略图
     * @author LXC
     * @date 2023/2/5 17:59
     */
    public static Image createThumbnail(byte[] bytes, Integer scaleSize){
        try (ByteArrayInputStream byteArrayInputStream = IoUtil.toStream(bytes)){
            BufferedImage bufferedImage = read(byteArrayInputStream);
            return createThumbnail(bufferedImage,scaleSize);
        }catch (Exception e){
            log.error("创建缩略图失败",e);
        }
        throw new BusinessException("创建缩略图失败");
    }

    /**
     * 添加水印
     * @author LXC
     * @date 2023/2/5 19:42
     */
    public static Image addMark(Image srcImage, Image pressImg, float alpha) {

        float percentage = 15 / 100f;

        int width = srcImage.getWidth(null);
        int height = srcImage.getHeight(null);
        BufferedImage bufferedImage = new BufferedImage(width, height, 1);
        Graphics2D graphics2D = bufferedImage.createGraphics();
        graphics2D.drawImage(srcImage, 0, 0, width, height, null);

        int oldPressImgWidth = pressImg.getWidth(null);
        int oldPressImgHeight = pressImg.getHeight(null);

        int pressImgWidth = (int)(srcImage.getWidth(null) * percentage);
        int pressImgHeight = pressImgWidth * oldPressImgHeight / oldPressImgWidth;
        int x = (width - pressImgWidth);
        int y = (height - pressImgHeight);
        graphics2D.setComposite(AlphaComposite.getInstance(10, alpha));
        // 右下角-水印
        graphics2D.drawImage(pressImg, x - 8, y- 2, pressImgWidth, pressImgHeight, null);

        // 中间-水印
        graphics2D.drawImage(pressImg, x/2, y/2, pressImgWidth, pressImgHeight, null);

        graphics2D.dispose();

        return bufferedImage;
    }

    /**
     * 图片去透明边
     * @author LXC
     * @date 2023/2/13 9:48
     */
    public static BufferedImage cutTransparentSide(byte[] bytes) {
        try (ByteArrayInputStream byteArrayInputStream = IoUtil.toStream(bytes)){
            BufferedImage pic = ImgUtil.read(byteArrayInputStream);

            int leftBorderX = 0;
            for (int x = 0; x < pic.getWidth(); x++) {
                for (int y = 0; y < pic.getHeight(); y++) {
                    if (!isTransparentPixel(pic, x, y)) {
                        leftBorderX = x;
                        x =  pic.getWidth();
                        break;
                    }
                }
            }

            int rightBorderX = 0;
            for (int x = pic.getWidth()-1; x >= 0; x--) {
                for (int y = 0; y < pic.getHeight(); y++) {
                    if (!isTransparentPixel(pic, x, y)) {
                        rightBorderX = x;
                        x =  0;
                        break;
                    }
                }
            }

            int topBorderY = 0;
            for (int y = 0; y <  pic.getHeight(); y++) {
                for (int x = leftBorderX; x < rightBorderX; x++) {
                    if (!isTransparentPixel(pic, x, y)) {
                        topBorderY = y;
                        y =  pic.getHeight();
                        break;
                    }
                }
            }

            int bottomBorderY = 0;
            for (int y = pic.getHeight()-1; y >= 0 ; y--) {
                for (int x = leftBorderX; x < rightBorderX; x++) {
                    if (!isTransparentPixel(pic, x, y)) {
                        bottomBorderY = y;
                        y =  0;
                        break;
                    }
                }
            }

            int w = rightBorderX - leftBorderX;
            int h = bottomBorderY - topBorderY;

            if(w == 0){
                return pic;
            }

            if(h == 0){
                return pic;
            }

            BufferedImage newImage = new BufferedImage(w, h,BufferedImage.TYPE_INT_ARGB);
            Image cut = cut(pic, new Rectangle(leftBorderX, topBorderY, w, h));
            Graphics2D graphics = newImage.createGraphics();
            graphics.drawImage(cut,0,0,null);
            graphics.dispose();

            return newImage;
        } catch (Exception e) {
            log.error("去透明边失败",e);
            throw new BusinessException("去除白边失败");
        }

    }


    /**
     * 一个像素是否透明
     *
     * @author LXC
     * @date 2022/11/29 15:35
     */
    public static Boolean isTransparentPixel(BufferedImage img, int x, int y) {
        int pixel = img.getRGB(x, y);
        return (pixel >> 24) == 0x00;
    }
}
